package net.pws.oos.security;

import java.io.IOException;
import java.util.Date;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import net.pws.common.util.StringUtils;
import net.pws.common.persistence.EntityManager;
import net.pws.common.security.SecurityContext;
import net.pws.common.security.filter.AbstractAuthenticateFilter;
import net.pws.common.security.spi.Principal;
import net.pws.oos.biz.model.OperateLog;

public class OperateLogFilter extends AbstractAuthenticateFilter {
    
    private EntityManager entityManager;
    
    public OperateLogFilter() {
        super();
    }
    
    public void setEntityManager(EntityManager entityManager) {
        this.entityManager = entityManager;
    }
    
    public void doFilter(ServletRequest request,
                         ServletResponse response,
                         FilterChain chain) throws IOException,
                                           ServletException {
        
        if (!(request instanceof HttpServletRequest)) {
            throw new ServletException("Can only process HttpServletRexquest");
        }
        
        if (!(response instanceof HttpServletResponse)) {
            throw new ServletException("Can only process HttpServletResponse");
        }
        
        HttpServletRequest httpRequest = (HttpServletRequest) request;
        try {
            saveLog(httpRequest);
        }
        catch (Exception e) {
        }
        
        chain.doFilter(request, response);
    }
    
    private void saveLog(HttpServletRequest request) {
        Principal principal = SecurityContext.getContext();
        if (principal == null || principal.hasPrivileged()) {
            return;
        }
        
        String uri = request.getRequestURI();
        if (StringUtils.isBlank(uri)) {
            return;
        }
        if (!AbstractAuthenticateFilter.BASIC_AUTH_FILTER_URL.equals(uri)) {
            return;
        }
        
        OperateLog log = new OperateLog();
        log.setUri(uri);
        log.setParameter(request.getQueryString());
        log.setType("login");
        log.setUser(SecurityUtils.currentUser());
        log.setOperateDate(new Date());
        
        String client = determineAccessType(request);
        if (StringUtils.isBlank(client)) {
            client = "by-web";
        }
        log.setClient(client);
        
        String ip = request.getHeader("X-Real-IP");
        if(StringUtils.isBlank(ip)) {
            ip = request.getRemoteAddr();
        }
        log.setIp(ip);
        entityManager.save(log);
    }
}
